package com.zhxy.config;

import com.zhxy.constants.Constants;
import com.zhxy.filter.TokenVerifyFilter;
import com.zhxy.handler.MyAuthenticationFailureHandler;
import com.zhxy.handler.MyAuthenticationSuccessHandler;
import com.zhxy.handler.MyLogoutSuccessHandler;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

@Configuration
public class SecurityConfig {

    @Resource
    private MyAuthenticationSuccessHandler authenticationSuccessHandler;

    @Resource
    private MyAuthenticationFailureHandler authenticationFailureHandler;

    @Resource
    private TokenVerifyFilter tokenVerifyFilter;

    @Resource
    private MyLogoutSuccessHandler myLogoutSuccessHandler;

    /**
     * 配置密码加密器
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity,CorsConfigurationSource corsConfigurationSource) throws Exception {
        return httpSecurity
                .formLogin((formLogin)->{
                    formLogin.loginProcessingUrl(Constants.LOGIN_URI)
                            .usernameParameter("loginAct")
                            .passwordParameter("loginPwd")
                            .successHandler(authenticationSuccessHandler)
                            .failureHandler(authenticationFailureHandler);
                })
                .authorizeHttpRequests((authorize)->{
                    authorize.requestMatchers(Constants.LOGIN_URI).permitAll()   // 对登录请求进行放行
                             .anyRequest().authenticated();   // 对其他请求都进行拦截
                })

                // 禁用请求跨域伪造
                .csrf(AbstractHttpConfigurer::disable)

                .cors(cors->{   // 支持跨域请求
                    cors.configurationSource(corsConfigurationSource);
                })

                .sessionManagement((session)->{
                    // Session策略
                    session.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
                })

                // 添加自定义的Filter
                .addFilterBefore(tokenVerifyFilter, LogoutFilter.class)

                // 退出登录
                .logout(logout -> {
                    logout.logoutUrl("/api/user/logout").logoutSuccessHandler(myLogoutSuccessHandler);
                })

                .build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource(){

        CorsConfiguration configuration=new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));  // 允许任何来源
        configuration.setAllowedMethods(Arrays.asList("*"));  // 允许任何请求方式
        configuration.setAllowedHeaders(Arrays.asList("*"));  // 允许任何请求头

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**",configuration);

        return source;
    }
}
